package filesystem.client;


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import filesystem.util.Messages;

/**
 * Classe que trata a conexão entre nós
 * 
 * Quando um outro nó tenta se comunicar esta classe assume o
 * controle da conexão.
 */

public class ClientConnection extends Thread {

	private Socket socket;					// Connection socket
	private InputStreamReader dataInStream;	// Input stream
	private DataOutputStream dataOutStream;	// Output stream
	
	/**
	 * Instancia um tratador de conexão.
	 *
	 * @param socket Socket da conexão tratada.
	 */
	public ClientConnection(Socket socket) {
		this.socket = socket;	
		
		// Get output stream from socket
		try {
			dataOutStream = new DataOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			System.out.println("ERROR: could not get output stream from socket");
			e.printStackTrace();
		}
		
		// Get input stream from socket
		try {
			dataInStream = new InputStreamReader(socket.getInputStream());
		} catch (IOException e) {
			System.out.println("ERROR: could not get input stream from socket");
			e.printStackTrace();
		}
	}

	/**
	 * Thread de tratamento de conexões.
	 * 
	 * Trata a conexão de um outro nó com este.
	 * 
	 * Mensagem de "GET":
	 * 	- get path/to/file
	 * 
	 * Respostas:
	 *  - ack ok fileLength
	 *  	- Transferência do arquivo
	 *  	   - ok
	 *  
	 *  - ack fail
	 */
	@Override
	public void run() {
		System.out.println("Running Client Connection!");

		BufferedReader reader;
		PrintWriter writer;
		String input;
		String[] content;

		try {
			reader = new BufferedReader(this.dataInStream );
			writer = new PrintWriter(this.dataOutStream, true);
			input = reader.readLine();
			
			System.out.println("Client Connection: " + input );
			content = input.split("[ ]+");

			// Recebe mensagem GET: iniciar processo de transferencia de arquivo
			if (content[0].equals( Messages.get )) {
				try {
					File file = new File(content[1]);
					byte [] buffer  = new byte [(int)file.length()];
					BufferedInputStream inputBuffer = new BufferedInputStream(new FileInputStream(file));
					inputBuffer.read(buffer, 0, buffer.length);
					writer.println(Messages.ack  + " " + Messages.ok + " " + file.length());
					writer.flush();
					System.out.println("Transferring file...");
					OutputStream output = socket.getOutputStream();
					output.write(buffer,0,buffer.length);
					output.flush();
					output.close();
					inputBuffer.close();
					System.out.println("Done");
					input = reader.readLine();
					System.out.println(input);
				} catch (FileNotFoundException e) {
					System.out.println("ERROR: requested file not found");
					writer.println(Messages.ack + " " + Messages.fail);
					writer.flush();
				} catch (IOException e) {
					System.out.println("ERROR: could not transfer file");
				}
			}else{
				System.out.println("Strange Message");
			}
			writer.close();
			reader.close();
			this.dataInStream.close();
			this.dataOutStream.close();
			this.socket.close();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

}
